package com.shiguiwu.springmybatis.designpattern.proxy.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @description: user代理
 * @author: stone
 * @date: Created by 2021/9/11 23:09
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.designpattern.proxy.dynamicproxy
 *
 *
 *
 *
 * subject.SayHello("jiankunking")这句话时，为什么会自动调用InvocationHandlerImpl的invoke方法？
 * 因为JDK生成的最终真正的代理类，它继承自Proxy并实现了我们定义的Subject接口，
 * 在实现Subject接口方法的内部，通过反射调用了InvocationHandlerImpl的invoke方法。
 * 包含生成本地class文件的demo：
 * http://download.csdn.net/detail/xunzaosiyecao/9597474
 * https://github.com/JianKunKing/DynamicProxyDemo
 * 通过分析代码可以看出Java 动态代理，具体有如下四步骤：
 *
 * 通过实现 InvocationHandler 接口创建自己的调用处理器；
 * 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类；
 * 通过反射机制获得动态代理类的构造函数，其唯一参数类型是调用处理器接口类型；
 * 通过构造函数创建动态代理类实例，构造时调用处理器对象作为参数被传入。

 */
public class UserProxy implements InvocationHandler {


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("接口方法调用开始");
        //执行方法
        System.out.println("method toGenericString:"+method.toGenericString());
        System.out.println("method name:"+method.getName());
        System.out.println("method args:"+(String)args[0]);
        System.out.println("接口方法调用结束");

        return null;
    }


    public static <T> T newDaoProxy(Class<T> mapperInterface) {
        ClassLoader classLoader = mapperInterface.getClassLoader();
        Class<?>[] interfaces = new Class[]{mapperInterface};
        //FacadeProxy proxy = new FacadeProxy();
        return (T) Proxy.newProxyInstance(classLoader, interfaces, new UserProxy());
    }
}
